// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.patent.service.impl;

import com.alibaba.fastjson.JSON;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.PatentClassTypeEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.MessageDao;
import com.liuxinlong.modules.dao.MessageTargetDao;
import com.liuxinlong.modules.dao.PatentDao;
import com.liuxinlong.modules.dao.PatentDepartmentDao;
import com.liuxinlong.modules.dao.PatentDepartmentSpecialDao;
import com.liuxinlong.modules.dao.PatentInventorRelationDao;
import com.liuxinlong.modules.dao.PatentNoticeDao;
import com.liuxinlong.modules.dao.PatentOperateRecordDao;
import com.liuxinlong.modules.dao.PatentSearchRecordDao;
import com.liuxinlong.modules.dao.RoleDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.MessageTarget;
import com.liuxinlong.modules.entity.Patent;
import com.liuxinlong.modules.entity.PatentDepartment;
import com.liuxinlong.modules.entity.PatentDepartmentSpecial;
import com.liuxinlong.modules.entity.PatentInventorRelation;
import com.liuxinlong.modules.entity.PatentNotice;
import com.liuxinlong.modules.entity.PatentOperateRecord;
import com.liuxinlong.modules.entity.PatentSearchRecord;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserRole;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.patent.dto.ImportPatentDto;
import com.liuxinlong.modules.patent.service.PatentService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 专利首页实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2023-09-06
 */
@Service
@Slf4j
public class PatentServiceImpl implements PatentService {

    @Autowired
    private PatentDao patentDao;

    @Autowired
    private PatentDepartmentDao patentDepartmentDao;

    @Autowired
    private PatentSearchRecordDao patentSearchRecordDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private PatentNoticeDao patentNoticeDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private PatentInventorRelationDao patentInventorRelationDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Autowired
    private PatentOperateRecordDao patentOperateRecordDao;

    @Autowired
    private PatentDepartmentSpecialDao patentDepartmentSpecialDao;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private MessageTargetDao messageTargetDao;

    @Override
    public Map<String, Object> queryPatentSpreadInfo() {
        Map<String, Object> resultMap = new HashMap<>();
        // 查询个人专利
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        Map<String, Object> userPatentMap = patentDao.getUserPatentCount(userId);
        resultMap.put("userPatentMap", userPatentMap);
        // 查询部门专利
        List<PatentDepartment> departmentList = patentDepartmentDao.getDepartmentByManager(userId);
        Map<String, Object> departmentPatentMap = new HashMap<>();
        User userInfo = userDao.selectById(userId);
        PatentDepartment patentDepartment = patentDepartmentDao.getDepartmentByChild(userInfo.getDepartment());
        if (ObjectUtils.isEmpty(departmentList)) {
            if (!ObjectUtils.isEmpty(patentDepartment)) {
                departmentPatentMap = patentDao.getDepartmentPatentCount(patentDepartment.getId());
            }
        } else {
            Set<String> manageDepartmentSet = departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toSet());
            if (!ObjectUtils.isEmpty(patentDepartment)) {
                manageDepartmentSet.add(patentDepartment.getId());
            }
            departmentPatentMap = patentDao.getDepartmentSetPatentCount(manageDepartmentSet);
        }
        if (ObjectUtils.isEmpty(departmentPatentMap)) {
            departmentPatentMap.put("appNum", 0);
            departmentPatentMap.put("invNum", 0);
            departmentPatentMap.put("totalNum", 0);
            departmentPatentMap.put("utiNum", 0);
        }
        resultMap.put("departmentPatentMap", departmentPatentMap);
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J020");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        UserRole manageRole = roleDao.getRoleBySn("J019");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        UserRole superManageRole = roleDao.getRoleBySn("J007");
        List<UserRoleRelation> existSuperList;
        if (ObjectUtils.isEmpty(superManageRole)) {
            existSuperList = new ArrayList<>();
        } else {
            existSuperList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), superManageRole.getId())).collect(Collectors.toList());
        }
        if (!existHighList.isEmpty() || !existList.isEmpty() || !existSuperList.isEmpty()) {
            Map<String, Object> campaignPatentMap = patentDao.getCampaignPatentCount();
            resultMap.put("campaignPatentMap", campaignPatentMap);
        }
        resultMap.put("highPermission", !existHighList.isEmpty() || !existList.isEmpty() || !existSuperList.isEmpty());

        return resultMap;
    }

    @Override
    public List<Map<String, Object>> queryPatentNoticeList(Map<String, Object> queryParam) {
        List<PatentNotice> noticeList = patentNoticeDao.pagePatentNoticeList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(noticeList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (PatentNotice notice : noticeList) {
            Map<String, Object> item = ObjectUtils.object2Map(notice);
            item.put("sort", sort);
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getPatentNoticeCount(Map<String, Object> queryParam) {
        return patentNoticeDao.getPatentNoticeCount(queryParam);
    }

    @Override
    public Map<String, Object> pagePatentInfo(Map<String, Object> queryParam) {
        Map<String, Object> dataMap = new HashMap<>();
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        queryParam.put("userId", userId);
        // 操作记录
//        PatentOperateRecord record = new PatentOperateRecord();
//        record.setId(SnowFlake.nextIdStr());
//        record.setOperateType(1);
//        record.setNewContent(JSON.toJSONString(queryParam));
//        record.setDescription("查询专利信息");
//        record.setCreateUser(userId);
//        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
//        record.setCreateTime(currentTime);
//        patentOperateRecordDao.insert(record);
        List<PatentDepartment> departmentList = patentDepartmentDao.getDepartmentByManager(userId);
        if (!ObjectUtils.isEmpty(departmentList)) {
            List<String> depList = departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
            queryParam.put("manageDepartment", depList);
        }
        PatentDepartmentSpecial special = patentDepartmentSpecialDao.getDepartmentSpecialById(userId);
        if (!ObjectUtils.isEmpty(special)) {
            if (queryParam.containsKey("manageDepartment")) {
                List<String> depList = (List<String>) queryParam.get("manageDepartment");
                List<String> allList = new ArrayList<>();
                allList.addAll(depList);
                allList.addAll(Arrays.asList(special.getBranch().split(",")));
                queryParam.put("manageDepartment", allList);
            } else {
                List<String> allList = Arrays.asList(special.getBranch().split(","));
                queryParam.put("manageDepartment", allList);
            }
        }
        dataMap.put("departmentPermission", !ObjectUtils.isEmpty(departmentList) || !ObjectUtils.isEmpty(special));
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J020");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("highPermission", !existHighList.isEmpty());
        UserRole manageRole = roleDao.getRoleBySn("J019");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("managePermission", !existList.isEmpty());
        UserRole superManageRole = roleDao.getRoleBySn("J007");
        List<UserRoleRelation> existSuperList;
        if (ObjectUtils.isEmpty(superManageRole)) {
            existSuperList = new ArrayList<>();
        } else {
            existSuperList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), superManageRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("superPermission", !existSuperList.isEmpty());
        if (!existHighList.isEmpty() || !existList.isEmpty() || !existSuperList.isEmpty()) {
            queryParam.put("manageDepartment", null);
            queryParam.put("userId", null);
        }
        List<Patent> originalList = patentDao.pagePatentList(queryParam);
        List<Map<String, Object>> resultList = completeResult(originalList, (int) queryParam.get("startNum"));
        dataMap.put("patentList", resultList);
        int totalNum = patentDao.getPatentCount(queryParam);
        dataMap.put("totalNum", totalNum);
        if (!existHighList.isEmpty() || !existList.isEmpty() || !existSuperList.isEmpty()) {
            // 申请表数据拼接
            List<Map<String, Object>> chartApplyList = patentDao.queryApplyChartData(queryParam);
            List<Map<String, Object>> sortApplyList = splicingChartData(chartApplyList, true);
            dataMap.put("chartDataList", sortApplyList);

            // 授权表数据拼接
            List<Map<String, Object>> chartAnnounceList = patentDao.queryAnnounceChartData(queryParam);
            List<Map<String, Object>> sortAnnounceList = splicingChartData(chartAnnounceList, true);
            dataMap.put("chartAnnounceDataList", sortAnnounceList);

            // 部门高价值数据拼接
            List<Map<String, Object>> chartDepList = patentDao.queryDepChartData(queryParam);
            List<Map<String, Object>> chartDepDataList = splicingChartData(chartDepList, false);
            dataMap.put("chartDepDataList", chartDepDataList);
        }
        return dataMap;
    }

    @Override
    public int getPatentCount(Map<String, Object> queryParam) {
        return patentDao.getPatentCount(queryParam);
    }

    @Override
    public void addPatent(Patent patent) {
        String patentId = SnowFlake.nextIdStr();
        patent.setImplementDate(TimeUtils.formatTime(patent.getImplementDate(), TimeFormatConstants.YYYY_MM, TimeFormatConstants.YYYY_MM_DD));
        patent.setId(patentId);
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        patent.setCreateUser(currentUser.getId());
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        patent.setCreateTime(currentTime);
        Map<String, Map<String, String>> userSnMap = userDao.getUserMapBySn();
        List<String> inventorList = Arrays.asList(patent.getInventor().split("/"));
        List<String> userNameList = new ArrayList<>(inventorList.size());
        List<PatentInventorRelation> relationList = new ArrayList<>(inventorList.size());
        int inventorSort = 1;
        for (String inventor : inventorList) {
            PatentInventorRelation patentInventorRelation = new PatentInventorRelation();
            patentInventorRelation.setId(SnowFlake.nextIdStr());
            patentInventorRelation.setPatentId(patentId);
            List<String> userInfo = Arrays.asList(inventor.split("-"));
            patentInventorRelation.setUserName(userInfo.get(0));
            userNameList.add(userInfo.get(0));
            patentInventorRelation.setSortNum(inventorSort);
            patentInventorRelation.setRemark("非系统用户");
            if (userInfo.size() > 1) {
                String userSn = userInfo.get(1);
                patentInventorRelation.setUserSn(userSn);
                if (userSnMap.containsKey(userSn)) {
                    Map<String, String> userData = userSnMap.get(userSn);
                    patentInventorRelation.setUserId(userData.get("id"));
                    patentInventorRelation.setRemark("系统内用户");
                }
            }
            relationList.add(patentInventorRelation);
            inventorSort++;
        }
        patent.setApplyCountry(1);
        patent.setInventor(StringUtils.replaceAll(StringUtils.strip(userNameList.toString(), "[]"), ",", "/").replaceAll(" +", ""));
        patentInventorRelationDao.insertBatch(relationList);
        patentDao.insert(patent);

        // 入库操作记录
        PatentOperateRecord record = new PatentOperateRecord();
        record.setId(SnowFlake.nextIdStr());
        record.setPatentId(patentId);
        record.setOperateType(2);
        record.setNewContent(JSON.toJSONString(patent));
        record.setDescription("新增专利信息");
        record.setCreateUser(currentUser.getId());
        record.setCreateTime(currentTime);
        patentOperateRecordDao.insert(record);
    }

    @Override
    @Transactional
    public void updatePatent(Patent patent, int pushFlag) {
        String patentId = patent.getId();
        Patent oldInfo = patentDao.selectById(patentId);
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，专利不存在！");
        }
        patent.setCreateUser(oldInfo.getCreateUser());
        patent.setCreateTime(oldInfo.getCreateTime());
        patent.setApplyCountry(oldInfo.getApplyCountry());
        if (!StringUtils.isEmpty(patent.getImplementDate())) {
            patent.setImplementDate(TimeUtils.formatTime(patent.getImplementDate(), TimeFormatConstants.YYYY_MM, TimeFormatConstants.YYYY_MM_DD));
        }
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        patent.setUpdateUser(currentUser.getId());
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        patent.setUpdateTime(currentTime);

        Map<String, Map<String, String>> userSnMap = userDao.getUserMapBySn();
        List<PatentInventorRelation> oldList = patentInventorRelationDao.pagePatentInventorRelation(patentId);
        String oldInventor = StringUtils.strip(oldList.stream().map(item ->
                                StringUtils.isEmpty(item.getUserSn()) ? item.getUserName() : item.getUserName() + "-" + item.getUserSn())
                        .collect(Collectors.toList()).toString(), "[]").replaceAll(",", "/")
                .replaceAll(" +", "");
        List<PatentInventorRelation> relationList = new ArrayList<>();
        if (!StringUtils.equals(oldInventor, patent.getInventor())) {
            List<String> idList = oldList.stream().map(item -> item.getId()).collect(Collectors.toList());
            if (!idList.isEmpty()) {
                patentInventorRelationDao.deleteBatchIds(idList);
            }
            List<String> inventorList = Arrays.asList(patent.getInventor().split("/"));
            List<String> userNameList = new ArrayList<>(inventorList.size());
//            relationList = new ArrayList<>(inventorList.size());
            int inventorSort = 1;
            for (String inventor : inventorList) {
                PatentInventorRelation patentInventorRelation = new PatentInventorRelation();
                patentInventorRelation.setId(SnowFlake.nextIdStr());
                patentInventorRelation.setPatentId(patentId);
                List<String> userInfo = Arrays.asList(inventor.split("-"));
                patentInventorRelation.setUserName(userInfo.get(0));
                userNameList.add(userInfo.get(0));
                patentInventorRelation.setSortNum(inventorSort);
                patentInventorRelation.setRemark("非系统用户");
                if (userInfo.size() > 1) {
                    String userSn = userInfo.get(1);
                    patentInventorRelation.setUserSn(userSn);
                    if (userSnMap.containsKey(userSn)) {
                        Map<String, String> userData = userSnMap.get(userSn);
                        patentInventorRelation.setUserId(userData.get("id"));
                        patentInventorRelation.setRemark("系统内用户");
                    }
                }
                relationList.add(patentInventorRelation);
                inventorSort++;
            }
            patent.setInventor(StringUtils.replaceAll(StringUtils.strip(userNameList.toString(), "[]"), ",", "/").replaceAll(" +", ""));
            patentInventorRelationDao.insertBatch(relationList);
        } else {
            patent.setInventor(oldInfo.getInventor());
            if (pushFlag == 1) {
                relationList = patentInventorRelationDao.pagePatentInventorRelation(patentId);
            }
        }
        patentDao.updateById(patent);
        // 入库操作记录
        PatentOperateRecord record = new PatentOperateRecord();
        record.setId(SnowFlake.nextIdStr());
        record.setPatentId(patentId);
        record.setOperateType(3);
        record.setOldContent(JSON.toJSONString(oldInfo));
        record.setNewContent(JSON.toJSONString(patent));
        record.setDescription("修改专利信息");
        record.setCreateUser(currentUser.getId());
        record.setCreateTime(currentTime);
        patentOperateRecordDao.insert(record);
        if (pushFlag == 0) {
            return;
        }
        String messageId = SnowFlake.nextIdStr();
        MessageConfiguration mc = new MessageConfiguration();
        mc.setId(messageId);
        mc.setBusinessType(MessagePushBusinessEnum.PATENT_MODULE.getValue());
        mc.setBusinessId(patentId);
        mc.setTitle(patent.getName());
        mc.setCreateUser(currentUser.getId());
        mc.setCreateTime(currentTime);
        mc.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
        mc.setPushType(2);
        String content = "专利号：" + patent.getPatentSn() + "\n"
                + "专利名称：" + patent.getName() + "\n"
                + "祝贺您的专利申请于" + TimeUtils.formatTime(patent.getAnnouncementDate(), TimeFormatConstants.YYYY_MM_DD, TimeFormatConstants.YYYY_MM_DD_STR) + "获得国家知识产权局颁发的专利证书！";
        mc.setContent(content);
        mc.setShareUser(currentUser.getName());
        mc.setTarget("3");
        messageDao.insert(mc);
        List<MessageTarget> messageTargetList = new ArrayList<>();
        for (PatentInventorRelation relation : relationList) {
            if (StringUtils.isEmpty(relation.getUserId())) {
                continue;
            }
            MessageTarget mt = new MessageTarget();
            mt.setId(SnowFlake.nextIdStr());
            mt.setMessageId(messageId);
            mt.setBusinessType(3);
            mt.setRelationId(relation.getUserId());
            messageTargetList.add(mt);
        }
        if (ObjectUtils.isEmpty(messageTargetList)) {
            return;
        }
        messageTargetDao.insertBatch(messageTargetList);
    }

    @Override
    public void deletePatent(String id) {

    }

    @Override
    public ImportResp importPatent(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
//                UserDepartment UserDepartment = covertToBean(record);
                return false;
//				try {
//					UserDepartmentDao.addDetail(UserDepartment);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入专利数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入专利数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<String[]> recordList = failRecords.stream().sorted(Comparator.comparing((String[] item) -> ((String) item[5]))).collect(Collectors.toList());
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : recordList) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("companySn", failRecord[0]);
                    item.put("caseSn", failRecord[1]);
                    item.put("department", failRecord[2]);
                    item.put("patentee", failRecord[3]);
                    item.put("patenteeFirst", failRecord[4]);
                    item.put("sn", failRecord[5]);
                    item.put("name", failRecord[6]);
                    item.put("brief", failRecord[7]);
                    item.put("inventor", failRecord[9]);
                    item.put("patentSn", failRecord[10]);
                    item.put("classType", failRecord[11]);
                    item.put("level", failRecord[12]);
                    item.put("status", failRecord[13]);
                    item.put("statusDesc", failRecord[14]);
                    item.put("applyDate", failRecord[15]);
                    item.put("announcementDate", failRecord[16]);
                    item.put("remark", failRecord[17]);
                    item.put("accessType", failRecord[18]);
                    item.put("implementProduct", failRecord[19]);
                    item.put("implementDate", failRecord[20]);
                    item.put("relationProject", failRecord[21]);
                    item.put("patentEngineer", failRecord[22]);
                    item.put("highValue", failRecord[23]);
                    if (StringUtils.isEmpty(failRecord[4])) {
                        System.out.println(item);
                    }
                    list.add(item);
                    sort++;
                }
//                List<Map> sortList = list.stream().sorted(Comparator.comparing((Map item) -> ((String) item.get("sn")))).collect(Collectors.toList());
                return list;
            }
        });
    }

    @Override
    public ImportResp batchAddPatent(List<ImportPatentDto> dataList) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        List<Map> failedList = new ArrayList<>();
        List<Patent> importList = new ArrayList<>();
        List<PatentInventorRelation> relationList = new ArrayList<>();
        Map<String, Map<String, String>> departmentMap = patentDepartmentDao.getDepartmentMapBySn();
        Map<String, Map<String, String>> patentMap = patentDao.getPatentMap();
        int sort = 1;
        Map<String, Map<String, String>> userSnMap = userDao.getUserMapBySn();
        for (ImportPatentDto patentDto : dataList) {
            if (StringUtils.isEmpty(patentDto.getPatentSn()) || patentMap.containsKey(patentDto.getPatentSn())) {
                Map item = ObjectUtils.object2Map(patentDto);
                item.put("message", "专利申请号为空或专利已存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            Patent patent = new Patent();
            String patentId = SnowFlake.nextIdStr();
            patent.setId(patentId);
            patent.setApplyCountry(1);
            patent.setPatentSn(patentDto.getPatentSn());
            patent.setName(patentDto.getName());
            patent.setSn(patentDto.getSn());
            patent.setBrief(patentDto.getBrief());
            if (!departmentMap.containsKey(patentDto.getDepartment())) {
                Map item = ObjectUtils.object2Map(patentDto);
                item.put("message", "部门不存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            patent.setDepartment(departmentMap.get(patentDto.getDepartment()).get("id"));
            patent.setCompanySn(patentDto.getCompanySn());
            patent.setCaseSn(patentDto.getCaseSn());
            if (!StringUtils.equals(patentDto.getPatenteeFirst().trim(), "热水器") && !StringUtils.equals(patentDto.getPatenteeFirst().trim(), "环境电器")) {
                Map item = ObjectUtils.object2Map(patentDto);
                item.put("message", "专利权人不存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            patent.setPatentee(patentDto.getPatentee());
            patent.setPatenteeFirst(StringUtils.equals(patentDto.getPatenteeFirst().trim(), "热水器") ? 1 : 2);
            patent.setPatentSn(patentDto.getPatentSn());
            if (PatentClassTypeEnum.getValueByName(patentDto.getClassType().trim()) == 0) {
                Map item = ObjectUtils.object2Map(patentDto);
                item.put("message", "类别不存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            // 状态匹配
            if (!StringUtils.equals(patentDto.getStatus(), "官方审查")
                    && !StringUtils.equals(patentDto.getStatus(), "授权")
                    && !StringUtils.equals(patentDto.getStatus(), "失效")) {
                Map item = ObjectUtils.object2Map(patentDto);
                item.put("message", "状态不存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            patent.setStatus(StringUtils.equals(patentDto.getStatus(), "官方审查") ? 1 : StringUtils.equals(patentDto.getStatus(), "授权") ? 2 : 3);
            patent.setStatusDesc(patentDto.getStatusDesc());
            // 发明人匹配系统内用户
            List<String> inventorList = Arrays.asList(patentDto.getInventor().split("/"));
            List<String> userNameList = new ArrayList<>(inventorList.size());
            int inventorSort = 1;
            for (String inventor : inventorList) {
                PatentInventorRelation patentInventorRelation = new PatentInventorRelation();
                patentInventorRelation.setId(SnowFlake.nextIdStr());
                patentInventorRelation.setPatentId(patentId);
                List<String> userInfo = Arrays.asList(inventor.split("-"));
                patentInventorRelation.setUserName(userInfo.get(0));
                userNameList.add(userInfo.get(0));
                patentInventorRelation.setSortNum(inventorSort);
                patentInventorRelation.setRemark("非系统用户");
                if (userInfo.size() > 1) {
                    String userSn = userInfo.get(1);
                    patentInventorRelation.setUserSn(userSn);
                    if (userSnMap.containsKey(userSn)) {
                        Map<String, String> userData = userSnMap.get(userSn);
                        patentInventorRelation.setUserId(userData.get("id"));
                        patentInventorRelation.setRemark("系统内用户");
                    }
                }
                relationList.add(patentInventorRelation);
                inventorSort++;
            }
            patent.setInventor(StringUtils.replaceAll(StringUtils.strip(userNameList.toString(), "[]"), ",", "/").replaceAll(" +", ""));
            patent.setClassType(PatentClassTypeEnum.getValueByName(patentDto.getClassType().trim()));
            String level = patentDto.getLevel();
            patent.setLevel(StringUtils.isEmpty(level) ? 4 : StringUtils.equals(level.trim(), "A级") ? 1 : StringUtils.equals(level.trim(), "B级") ? 2 : StringUtils.equals(level.trim(), "C级") ? 3 : 4);
            patent.setHighValue(StringUtils.isEmpty(patentDto.getHighValue()) ? 3 : StringUtils.equals(patentDto.getHighValue().trim(), "高价值-预测") ? 1 : StringUtils.equals(patentDto.getHighValue().trim(), "高价值-确定") ? 2 : 3);
            patent.setApplyDate(patentDto.getApplyDate());
            patent.setAnnouncementDate(patentDto.getAnnouncementDate());
            patent.setAccessType(StringUtils.equals(patentDto.getAccessType().trim(), "自主申请") ? 1 : 2);
            patent.setImplementProduct(patentDto.getImplementProduct());
            patent.setImplementDate(StringUtils.isEmpty(patentDto.getImplementDate()) ? null : TimeUtils.formatTime(patentDto.getImplementDate(), TimeFormatConstants.YYYYDOTMM, TimeFormatConstants.YYYY_MM_DD));
            patent.setRelationProject(patentDto.getRelationProject());
            patent.setPatentEngineer(patentDto.getPatentEngineer());
            patent.setRemark(patentDto.getRemark());
            patent.setCreateUser(currentUser.getId());
            patent.setCreateTime(currentTime);
            importList.add(patent);
        }
        if (!importList.isEmpty()) {
            patentDao.insertBatch(importList);
        }
        if (!relationList.isEmpty()) {
            patentInventorRelationDao.insertBatch(relationList);
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(failedList.size() > 0 ? ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() : ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setRetMessage(failedList.size() > 0 ? "导入专利信息部分成功" : "导入专利信息成功");
        resp.setFailedList(failedList);
        resp.setTotal(dataList.size());
        resp.setSuccessTotal(importList.size());
        resp.setFailedTotal(failedList.size());
        return resp;
    }

    @Override
    public void exportPatent(Map<String, Object> param, HttpServletResponse response) {
        param.put("startNum", 0);
        param.put("pageSize", 10000);
        Map<String, Object> dataMap = new HashMap<>();
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        param.put("userId", userId);
        List<PatentDepartment> departmentList = patentDepartmentDao.getDepartmentByManager(userId);
        if (!ObjectUtils.isEmpty(departmentList)) {
            List<String> depList = departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
            param.put("manageDepartment", depList);
        }
        PatentDepartmentSpecial special = patentDepartmentSpecialDao.getDepartmentSpecialById(userId);
        if (!ObjectUtils.isEmpty(special)) {
            if (param.containsKey("manageDepartment")) {
                List<String> depList = (List<String>) param.get("manageDepartment");
                List<String> allList = new ArrayList<>();
                allList.addAll(depList);
                allList.addAll(Arrays.asList(special.getBranch().split(",")));
                param.put("manageDepartment", allList);
            } else {
                List<String> allList = Arrays.asList(special.getBranch().split(","));
                param.put("manageDepartment", allList);
            }
        }
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J020");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("highPermission", !existHighList.isEmpty());
        UserRole manageRole = roleDao.getRoleBySn("J019");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("managePermission", !existList.isEmpty());
        UserRole superManageRole = roleDao.getRoleBySn("J007");
        List<UserRoleRelation> existSuperList;
        if (ObjectUtils.isEmpty(superManageRole)) {
            existSuperList = new ArrayList<>();
        } else {
            existSuperList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), superManageRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("superPermission", !existSuperList.isEmpty());
        if (!existHighList.isEmpty() || !existList.isEmpty() || !existSuperList.isEmpty()) {
            param.put("manageDepartment", null);
            param.put("userId", null);
        }
        List<Patent> originalList = patentDao.pagePatentList(param);
        ExcelData data = new ExcelData();
        data.setFileName("专利信息导出excel.xlsx");
//        String[] head = {"序号", "部门", "专利名称", "专利内容简介", "发明人", "专利号/申请号", "申请日期", "授权公告日"};
        String[] head = {"我司编号", "三友案号", "部门", "申请人", "第1申请人", "序列号", "专利名称", "专利内容简介", "发明人", "发明人-工号", "专利号/申请号", "类别", "级别", "状态", "进展", "申请日期", "授权公告日", "备注", "获取方式", "实施产品", "实施日期", "关联项目号", "专利工程师", "高价值专利"};
        data.setHead(head);
        String[][] dataList = new String[originalList.size()][head.length];
        List<Patent> patentList = originalList.stream().sorted(Comparator.comparing(item -> item.getSn())).collect(Collectors.toList());
        int index = 0;
        Map<String, Map<String, String>> departmentMap = patentDepartmentDao.getDepartmentMap();
        for (Patent item : patentList) {
            dataList[index][0] = item.getCompanySn();
            dataList[index][1] = item.getCaseSn();
            dataList[index][2] = departmentMap.containsKey(item.getDepartment()) ? departmentMap.get(item.getDepartment()).get("sn") : "";
            dataList[index][3] = item.getPatentee();
            dataList[index][4] = item.getPatenteeFirst() == 1 ? "热水器" : "环境电器";
            dataList[index][5] = String.valueOf(item.getSn());
            dataList[index][6] = item.getName();
            dataList[index][7] = item.getBrief();
            dataList[index][8] = item.getInventor();
            // 发明人-工号
            List<PatentInventorRelation> relationList = patentInventorRelationDao.pagePatentInventorRelation(item.getId());
            List<String> inventerList = new ArrayList<>(relationList.size());
            for (PatentInventorRelation relation : relationList) {
                if (StringUtils.isEmpty(relation.getUserSn())) {
                    inventerList.add(relation.getUserName());
                    continue;
                }
                inventerList.add(relation.getUserName() + "-" + relation.getUserSn());
            }
            dataList[index][9] = StringUtils.replaceAll(StringUtils.strip(inventerList.toString(), "[]"), ",", "/");
            dataList[index][10] = item.getPatentSn();
            dataList[index][11] = PatentClassTypeEnum.getNameByValue(item.getClassType());
            dataList[index][12] = item.getLevel() == 1 ? "A级" : item.getLevel() == 2 ? "B级" : item.getLevel() == 3 ? "C级" : "";
            dataList[index][13] = item.getStatus() == 1 ? "官方审查" : item.getStatus() == 2 ? "授权" : "失效";
            dataList[index][14] = item.getStatusDesc();
            dataList[index][15] = StringUtils.isEmpty(item.getApplyDate()) ? "" : item.getApplyDate().replaceAll("-", "/");
            dataList[index][16] = StringUtils.isEmpty(item.getAnnouncementDate()) ? "" : item.getAnnouncementDate().replaceAll("-", "/");
            dataList[index][17] = item.getRemark();
            dataList[index][18] = item.getAccessType() == 1 ? "自主申请" : "";
            dataList[index][19] = item.getImplementProduct();
            dataList[index][20] = StringUtils.isEmpty(item.getImplementDate()) ? "" : item.getImplementDate().substring(0, 7).replaceAll("-", ".");
            dataList[index][21] = item.getRelationProject();
            dataList[index][22] = item.getPatentEngineer();
            dataList[index][23] = item.getHighValue() == 1 ? "高价值-预测" : item.getHighValue() == 2 ? "高价值-确定" : "";
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public Map<String, Object> pagePatentOperateHistory(Map<String, Object> queryParam) {
        int periodType = (int) queryParam.get("periodType");
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        String startTime = "";
        if (periodType == 1) {
            startTime = TimeUtils.getBeforeDay(currentTime, 7, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (periodType == 2) {
            startTime = TimeUtils.getBeforeDay(currentTime, 30, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (periodType == 3) {
            startTime = TimeUtils.getBeforeDay(currentTime, 180, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (periodType == 4) {
            startTime = TimeUtils.getBeforeDay(currentTime, 365, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        }
        queryParam.put("startTime", startTime);
        queryParam.put("endTime", currentTime);
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("userId", currentUser.getId());
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J020");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        boolean highPermission = !existHighList.isEmpty();
        UserRole superManageRole = roleDao.getRoleBySn("J007");
        List<UserRoleRelation> existSuperList;
        if (ObjectUtils.isEmpty(superManageRole)) {
            existSuperList = new ArrayList<>();
        } else {
            existSuperList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), superManageRole.getId())).collect(Collectors.toList());
        }
        boolean superPermission = !existSuperList.isEmpty();
        if (highPermission && !superPermission) {
            queryParam.put("operateType", 1);
        } else if (superPermission) {
            queryParam.put("userId", null);
        } else if (!highPermission && !superPermission) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户无权限查看！");
        }
        List<PatentOperateRecord> recordList = patentOperateRecordDao.pagePatentOperateList(queryParam);
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        int sort = (int) queryParam.get("startNum") + 1;
        Map<String, Object> dataMap = new HashMap<>();
        List<Map<String, Object>> resultList = new ArrayList<>(recordList.size());
        for (PatentOperateRecord record : recordList) {
            Map<String, Object> item = ObjectUtils.object2Map(record);
            item.put("userName", userMap.containsKey(record.getCreateUser()) ? userMap.get(record.getCreateUser()).get("name") : "");
            item.put("sort", sort);
            resultList.add(item);
            sort++;
        }
        dataMap.put("dataList", resultList);
        int totalNum = patentOperateRecordDao.getPatentOperateCount(queryParam);
        dataMap.put("totalNum", totalNum);
        return dataMap;
    }

    @Override
    public int getPatentOperateHistoryCount(Map<String, Object> queryParam) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("userId", currentUser.getId());
        return patentOperateRecordDao.getPatentOperateCount(queryParam);
    }

    @Override
    public void deletePatentOperateHistory(String id) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        if (StringUtils.isNotEmpty(id)) {
            PatentSearchRecord record = patentSearchRecordDao.selectById(id);
            if (ObjectUtils.isEmpty(record)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "搜索记录不存在！");
            }
            if (!StringUtils.equals(userId, record.getCreateUser())) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "搜索记录不存在！");
            }
            patentSearchRecordDao.deleteById(id);
            return;
        }
        patentSearchRecordDao.deleteHistoryByUser(userId);
    }

    @Override
    public Map<String, Object> queryPatentExpand(String id) {
        Patent patent = patentDao.selectById(id);
        if (ObjectUtils.isEmpty(patent)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "专利信息不存在！");
        }
        Map<String, Object> dataMap = new HashMap<>();
        List<PatentInventorRelation> inventors = patentInventorRelationDao.pagePatentInventorRelation(id);
        List<Map<String, Object>> inventorList = new ArrayList<>(inventors.size());
        int inventorSort = 1;
        for (PatentInventorRelation inventorRelation : inventors) {
            Map<String, Object> item = new HashMap<>();
            item.put("sort", inventorSort);
            item.put("name", inventorRelation.getUserName());
            item.put("sn", inventorRelation.getUserSn());
            item.put("remark", inventorRelation.getRemark());
            inventorList.add(item);
            inventorSort++;
        }
        dataMap.put("inventorList", inventorList);
        List<String> applys = Arrays.asList(patent.getPatentee().split("\\+"));
        List<Map<String, Object>> applyList = new ArrayList<>();
        int applySort = 1;
        for (String userName : applys) {
            Map<String, Object> item = new HashMap<>();
            item.put("sort", applySort);
            item.put("name", userName);
            applyList.add(item);
            applySort++;
        }
        dataMap.put("applyList", applyList);
        List<Map<String, Object>> processList = new ArrayList<>();
        Map<String, Object> firstStep = new HashMap<>();
        firstStep.put("node", 1);
        firstStep.put("createTime", patent.getApplyDate());
        processList.add(firstStep);
        if (!StringUtils.isEmpty(patent.getAnnouncementDate())) {
            Map<String, Object> threeStep = new HashMap<>();
            threeStep.put("node", 3);
            threeStep.put("createTime", patent.getAnnouncementDate());
            processList.add(threeStep);
        }
        dataMap.put("processList", processList);
        List<Map<String, Object>> processRecordList = new ArrayList<>();
        dataMap.put("processRecordList", processRecordList);
        return dataMap;
    }

    @Override
    public List<String> getUserDepartment() {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        List<PatentDepartment> departmentList = patentDepartmentDao.getDepartmentList();
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J020");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        if (!existHighList.isEmpty()) {
            return departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
        }
        // 专利
        UserRole manageRole = roleDao.getRoleBySn("J019");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        if (!existList.isEmpty()) {
            return departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
        }
        UserRole superManageRole = roleDao.getRoleBySn("J007");
        List<UserRoleRelation> existSuperList;
        if (ObjectUtils.isEmpty(superManageRole)) {
            existSuperList = new ArrayList<>();
        } else {
            existSuperList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), superManageRole.getId())).collect(Collectors.toList());
        }
        if (!existSuperList.isEmpty()) {
            return departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
        }
        // 固资
        UserRole assetsManageRole = roleDao.getRoleBySn("J021");
        List<UserRoleRelation> existAssetsList;
        if (ObjectUtils.isEmpty(assetsManageRole)) {
            existAssetsList = new ArrayList<>();
        } else {
            existAssetsList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), assetsManageRole.getId())).collect(Collectors.toList());
        }
        if (!existAssetsList.isEmpty()) {
            return departmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
        }

        List<String> existDepList = new ArrayList<>();
        List<PatentDepartment> manageDepartmentList = patentDepartmentDao.getDepartmentByManager(userId);
        if (!ObjectUtils.isEmpty(manageDepartmentList)) {
            List<String> depList = manageDepartmentList.stream().map(PatentDepartment::getId).collect(Collectors.toList());
            existDepList.addAll(depList);
        }
        PatentDepartmentSpecial special = patentDepartmentSpecialDao.getDepartmentSpecialById(userId);
        if (!ObjectUtils.isEmpty(special)) {
            existDepList.addAll(Arrays.asList(special.getBranch().split(",")));
        }
        return existDepList;
    }

    /**
     * 补全数据
     *
     * @param originalList 原始数据
     * @param startNum     起始数据
     * @return 补全后数据
     */
    private List<Map<String, Object>> completeResult(List<Patent> originalList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>(originalList.size());
        Map<String, Map<String, String>> departmentMap = patentDepartmentDao.getDepartmentMap();
        int sort = startNum + 1;
        for (Patent item : originalList) {
            Map<String, Object> map = ObjectUtils.object2Map(item);
            map.put("sort", sort);
            map.put("departmentName", departmentMap.containsKey(item.getDepartment()) ? departmentMap.get(item.getDepartment()).get("name") : "");
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("部门名称不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 50) {
                addRowError("部门名称长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("部门编码不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 20) {
                addRowError("部门编码长度不能超过20", rowErrors);
            }
        }
        if (record.length > 2 && !StringUtils.isEmpty(record[2].trim())) {
            if (record[2].trim().length() > 200) {
                addRowError("描述长度不能超过200", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

    /**
     * 拼接图表数据
     *
     * @param chartList 原始数据列表
     * @return 拼接后数据列表
     */
    private List<Map<String, Object>> splicingChartData(List<Map<String, Object>> chartList, boolean sortFlag) {
        List<Map<String, Object>> chartDataList = new ArrayList<>(chartList.size());
        Map<String, Long> yearMap = new HashMap<>();
        for (Map<String, Object> item : chartList) {
            String year = (String) item.get("year");
            long num = (long) item.get("dataNum");
            if (yearMap.containsKey(year)) {
                long yearTotal = yearMap.get(year) + num;
                yearMap.put(year, yearTotal);
            } else {
                yearMap.put(year, num);
            }
            int classType = (int) item.get("classType");
            item.put("category", PatentClassTypeEnum.getNameByValue(classType));
            chartDataList.add(item);
        }
        for (String year : yearMap.keySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("year", year);
            item.put("category", "全部");
            item.put("dataNum", yearMap.get(year));
            chartDataList.add(item);
        }
        if (sortFlag) {
            List<Map<String, Object>> sortList = chartDataList.stream().sorted(Comparator.comparing((Map item) -> (Integer.valueOf((String) item.get("year"))))).collect(Collectors.toList());
            return sortList;
        } else {
            return chartDataList;
        }
    }
}
